#pragma once

#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <string.h>
#include <sstream>
#include <iomanip>
#include <condition_variable>
#include <unordered_map>
#include <memory>
#include <sys/signalfd.h>
#include <signal.h>
#include <utility>
#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/metadata.h>
#include <cppconn/exception.h>

using std::cerr;
using std::condition_variable;
using std::cout;
using std::endl;
using std::mutex;
using std::queue;
using std::shared_ptr;
using std::string;
using std::thread;
using std::unique_lock;
using std::unordered_map;
using std::vector;

class Parser;
using ParserPtr = Parser *;
using stringVecPtr = shared_ptr<vector<string>>;

constexpr static int EPOLL_EVENT_LEN = 128;
constexpr static int PROTOCOL_BUF_LEN = 4096;

constexpr static const char *ROOT_PATH = "/home/met/terminal_cloud_disk/";

constexpr static const char *MYSQL_HOST_ = "localhost";
constexpr static const short MYSQL_PORT_ = 3306;
constexpr static const char *MYSQL_USER_ = "root";
constexpr static const char *MYSQL_PWD_ = "123";
constexpr static const char *MYSQL_DB_ = "terminal_cloud_netdisk";

#define DEBUG
#define ERR_CHECK(var, val, msg) \
    if (val == var)              \
    {                            \
        perror(msg);             \
        return;                  \
    }
#define ERR_CHECK_RETURN(var, val, msg) \
    if (val == var)                     \
    {                                   \
        perror(msg);                    \
        return -1;                      \
    }

class NoCopyable
{
public:
    NoCopyable() {}

private:
    NoCopyable(const NoCopyable &elm) {}
    NoCopyable operator=(const NoCopyable &elm) { return elm; }
};

enum class IsClose : short
{
    TRUE,
    FALSE,
    HALF,
};

enum class Behavior
{
    REGISTER, // 注册
    LOGIN,    // 登录
    LS,
    CD,
    PWD,
    MKDIR,
    REMOVE, // 删除文件或非空文件夹
    TOKEN,
    GETS,     // 下载文件
    PUTS,     // 上传文件
    TRANSFER, // 传输文件
    OK,       // 成功
    ERR,      // 失败
};

// 服务端与客户端通信的协议
struct Protocol
{
    enum Behavior behavior_; // 行为
    int len_{};
    char buf_[PROTOCOL_BUF_LEN];
};

struct VirtualDirec
{
    int id;
    int uid;
    int code;
    int precode;
    string fname;
    string md5sum;
};

struct File
{
    int fid;
    string fname;
    string md5sum;
    int linked;
};

struct User
{
    int uid;
    string uname;
    string upwd;
    string encrypt;
    string root_path;
};